<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Document</title>
</head>
<style>
.box{
    width: 400px;
    height:400px;
    border:2px solid #00f;
    position: relative;
    margin:50px;
}
.middle{
    width: 400px;
    height: 400px;
    border:1px solid #000;
    position: relative;
}
.small{
    margin-top:10px;
}
.small img{
    border:1px solid #000;
    margin-left:10px;
}
.middle .shade{
    position: absolute;
    left:0;
    top:0;
    background-color: rgba(255,255,0,0.4);
    width: 200px;
    height: 200px;
    display:none;
}
.big{
    width: 400px;
    height: 400px;
    border:1px solid #f00;
    position: absolute;
    left:105%;
    top:0;
    background-image: url("./images/1.jpg" );
    background-size:800px 800px;
    overflow: hidden;
    display:none;
}
</style>
<body>
<div style="height:300px;"></div>
<div class="box">
    <div class="middle">
        <img src="./images/1.jpg" alt="" width="400px" height="400px">
       
        <div class="shade"></div>
    </div>
    <div class="small">
        <img src="" alt="">
      
    </div>
    <div class="big"></div>
</div>
</body>
<script type="text/javascript">
function Enlarge(classname){
    this.box = document.querySelector("."+classname);
    this.smallImgs = this.box.querySelectorAll(".small img");
    this.middleImg = this.box.querySelector(".middle>img");
    this.big = this.box.querySelector(".big");
    this.middle = this.box.querySelector(".middle");
    this.shade = this.box.querySelector(".shade");
    this.smallImgs[0].style.borderColor = 'red'
}
Enlarge.prototype.init = function(){
    // 给所有的小图片绑定单击事件
    for(let i=0;i<this.smallImgs.length;i++){
        this.smallImgs[i].onclick = ()=>{
            this.smallImgClick(i)
        }
    }
    // 给中等盒子绑定鼠标移入事件
    this.middle.onmouseover = ()=>{
        this.shade.style.display = 'block';
        // 大盒子悉尼市
        this.big.style.display = 'block';
        // 给中等盒子添加鼠标移动事件
        this.middle.onmousemove = e=>{
            this.move()
        }
    }   
    // 移出事件
    this.middle.onmouseout = ()=>{
        this.shade.style.display = 'none';
        this.big.style.display = 'none';
    }
}
Enlarge.prototype.move = function(){
    var e = e || window.event;
    // 当使用offsetX和offsetY对div进行赋值left和top的时候，效果是一闪一闪的，因为当获取到光标在中等盒子上的位置，给遮罩进行改变left和top的时候，offsetX和offsetY的值就变成光标在遮罩上的offsetX和offsetY*/
    var x = e.pageX;
    var y = e.pageY;
    this.setShadeMove(x,y)
    this.setBigImgMove();
}
Enlarge.prototype.setBigImgMove = function(){
    // 计算遮罩在中等盒子上移动过的比例：移动过的距离/中等盒子的尺寸
    var xpercent = this.shade.offsetLeft/this.middle.clientWidth;
    var ypercent = this.shade.offsetTop/this.middle.clientHeight;
    // 使用这个比例计算大盒子上的背景图移动的距离：比例*背景图的尺寸
    // 获取大盒子的背景图的宽和高
    var bigBgSize = getStyle(this.big,"background-size")
    // console.log(bigBgSize);
    var bigBgWidth = parseFloat(bigBgSize.split(" ")[0])
    var bigBgHeight = parseFloat(bigBgSize.split(" ")[1])
    var bigLeft = xpercent * bigBgWidth
    var bigTop = ypercent * bigBgHeight
    // 根据这个距离设置大盒子的背景图的位置
    this.big.style.backgroundPosition = `-${bigLeft}px -${bigTop}px`
}
Enlarge.prototype.setShadeMove = function(x,y){
    var l = x - this.box.offsetLeft - this.shade.offsetWidth/2
    var t = y - this.box.offsetTop - this.shade.offsetHeight/2
    if(l<=0){
        l = 0;
    }
    if(t<=0){
        t = 0;
    }
    if(l>=this.middle.clientWidth - this.shade.offsetWidth){
        l=this.middle.clientWidth - this.shade.offsetWidth
    }
    if(t>=this.middle.clientHeight - this.shade.offsetHeight){
        t=this.middle.clientHeight - this.shade.offsetHeight
    }
    this.shade.style.left = l + "px"
    this.shade.style.top = t + "px" 
}
Enlarge.prototype.smallImgClick = function(i){
    // 将所有小图片的边框颜色改成黑色
    for(var j=0;j<this.smallImgs.length;j++){
        this.smallImgs[j].style.borderColor = '#000';
    }
    // 将当前点击的这个图片的边框颜色变成红色
    this.smallImgs[i].style.borderColor = 'red';
    // 获取当前点击的这个小图片的路径，看看是1.jpg还是2.jpg - 改变中等图片
    var smallImgPath = this.smallImgs[i].getAttribute("src");
    // 截取到 数字.jpg
    // 找点最后一次出现的位置
    var index = smallImgPath.lastIndexOf(".")
    var suffix = smallImgPath.slice(index-1)
    // 拼接中等图片的路径
    var middleImgPath = "./images/middle"+suffix;
    // 设置中等图片的路径
    this.middleImg.setAttribute("src",middleImgPath)
    // 拼接大图的路径
    var bigImgPath = "./images/big"+suffix;
    // 使用大图的路径修改大盒子的背景
    this.big.style.backgroundImage = `url("${bigImgPath}")`;
}
var e = new Enlarge("box");
e.init()



function getStyle(ele,attr){
    if(window.getComputedStyle){
        return window.getComputedStyle(ele)[attr]
    }else{
        return ele.currentStyle[attr];
    }
}
</script>
</html>